import java.io.IOException;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.lang.*;

public class TrainController {
	private static TrainModel associatedTrainModel;
	private static double errorcount=0;
	
	public static String speed = "Speed: ";
	public static JLabel lblSpeed; 
	public static String doors = "Doors: ";
	public static JLabel lblDoors; 
	public static String lights = "Lights: ";
	public static JLabel lblLights;
	public static String fail = "System: ";
	public static JLabel lblFail;
	public static String authority = "Authority: ";
	public static JLabel lblauthority;
	public static String brakes = "Brakes: ";
	public static JLabel lblBrakes;   	
	public static JButton b1,b2,b3,b4,b5,b6,b7,b8,b9;

	static JFrame frame;
	
	static TNBundle bundle;

	public static void main(String[] args) throws IOException, InterruptedException 
	{
		TrainController window = new TrainController(associatedTrainModel);
	}
	
	public static void receiveBundle(TNBundle b)
	{
		bundle = b;
		doors  = (associatedTrainModel.doorsOpen) ? "Doors: Open" : "Doors: Closed";
		lights = (associatedTrainModel.lightsOn) ? "Lights: On" : "Lights: Off";
		fail   = (associatedTrainModel.failedBrake || associatedTrainModel.failedSignalPickup || associatedTrainModel.failedTrainEngine) ? "System: FAIL" : "System: OK";
		brakes = (associatedTrainModel.emergencyBrakeOn) ? "Brakes: Emergency" : (associatedTrainModel.brakeOn) ?  "Brakes: On" : "Brakes: Off";
		
		if(associatedTrainModel.velocity<b.newSpeed){
		double t=b.newSpeed-associatedTrainModel.velocity;
		errorcount=errorcount+t;
		associatedTrainModel.setPower(1*errorcount+2000*t);
		} 
		else
		errorcount=0;
	}
	
	public TrainController(TrainModel associatedTrainModel) 
	{
		this.associatedTrainModel = associatedTrainModel;
		initialize();
	}

	private void initialize() 
	{
		frame = new JFrame("Train Controller");
		frame.setBounds(100, 100, 450, 300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(new GridLayout(0,3));
		frame.setVisible(true);
		lblSpeed = new JLabel(speed);
		lblDoors = new JLabel(doors);
		lblLights = new JLabel(lights);
		lblFail = new JLabel(fail);
		lblauthority = new JLabel(authority);
		lblBrakes = new JLabel(brakes);
		
		b1 = new JButton("Open Doors");
		ActionListener open_doors = new openDoors();
		b1.addActionListener(open_doors);
		
		b2 = new JButton("Close Doors");
		ActionListener close_doors = new closeDoors();
		b2.addActionListener(close_doors);
		
		b3 = new JButton("Pull Brake");
		ActionListener pull_brake = new pullBrake();
		b3.addActionListener(pull_brake);
		
		b4 = new JButton("Lights On");
		ActionListener lights_on = new lightsOn();
		b4.addActionListener(lights_on);
		
		b5 = new JButton("Lights Off");
		ActionListener lights_off = new lightsOff();
		b5.addActionListener(lights_off);
		
		b6 = new JButton("Pull E-Brake");
		ActionListener pull_E_brake = new pullEBrake();
		b6.addActionListener(pull_E_brake);
		
		b7 = new JButton("Send Power");
		ActionListener send_power = new sendPower();
		b7.addActionListener(send_power);
		
		b8 = new JButton("Set Temperature");
		ActionListener set_temp = new sendtemp();
		b8.addActionListener(set_temp);
		
		b9 = new JButton("Release Brake");
		ActionListener release_brake = new releaseBrake();
		b9.addActionListener(release_brake);
		
		frame.getContentPane().add(lblSpeed);
		frame.getContentPane().add(lblDoors);
		frame.getContentPane().add(lblLights);
		frame.getContentPane().add(lblFail);
		frame.getContentPane().add(lblauthority);
		frame.getContentPane().add(lblBrakes);
		frame.getContentPane().add(b1);
		frame.getContentPane().add(b2);
		frame.getContentPane().add(b3);
		frame.getContentPane().add(b4);
		frame.getContentPane().add(b5);
		frame.getContentPane().add(b6);
		frame.getContentPane().add(b7);
		frame.getContentPane().add(b8);
		frame.getContentPane().add(b9);
	}
	public class openDoors implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			if(associatedTrainModel.velocity != 0) return;

			associatedTrainModel.openDoors();
			lblDoors.setText("Doors: Open");
			System.out.println("Open Doors");
		}
	}
	public class closeDoors implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			associatedTrainModel.closeDoors();
			lblDoors.setText("Doors: Closed");
			System.out.println("Close Doors");
		}
	}
	public class lightsOn implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			associatedTrainModel.turnLightsOn();
			lblLights.setText("Lights: On");
			System.out.println("Lights On");
		}
	}
	public class lightsOff implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			associatedTrainModel.turnLightsOff();
			lblLights.setText("Lights: Off");
			System.out.println("Lights Off");
		}
	}
	public class pullEBrake implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			associatedTrainModel.pullEmergencyBrake();
			lblBrakes.setText("Brakes: On (emergency)");
			System.out.println("Pull E-Brake");
		}
	}
	public class pullBrake implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			associatedTrainModel.pullBrake();
			lblBrakes.setText("Brakes: On");
			System.out.println("Pull Brake");
		}
	}
	public class releaseBrake implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			associatedTrainModel.releaseBrake();
			lblBrakes.setText((associatedTrainModel.emergencyBrakeOn) ? "Brakes: On (emergency)" : "Brakes: Off");
			System.out.println("Release Brake");
		}
	}
	public class sendPower implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			setPower();
			System.out.println("Send Power");
		}
	}
	public class sendtemp implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			associatedTrainModel.setTemperature(23);
			System.out.println("Send temperature (always 23 C)");
		}
	}
	
	public void setPower()
	{
		if(associatedTrainModel.velocity < bundle.newSpeed)
		{
			double t = bundle.newSpeed - associatedTrainModel.velocity;
			errorcount = errorcount + t;
			associatedTrainModel.setPower(1*errorcount+2000*t);
		}
	}
}
